// 组件注册系统
// 提供动态组件加载、主题切换、插件系统支持

import React, { ComponentType, lazy, Suspense } from 'react';
import { FullBaseProps } from '../base/BaseComponent';

// 组件元数据接口
export interface ComponentMetadata {
  name: string;
  version: string;
  description: string;
  category: ComponentCategory;
  tags: string[];
  dependencies: string[];
  author: string;
  license: string;
  deprecated?: boolean;
  experimental?: boolean;
}

// 组件类别
export type ComponentCategory = 
  | 'layout' 
  | 'navigation' 
  | 'input' 
  | 'display' 
  | 'feedback' 
  | 'overlay' 
  | 'editor' 
  | 'graph' 
  | 'utility';

// 组件配置接口
export interface ComponentConfig {
  lazy?: boolean;
  preload?: boolean;
  fallback?: ComponentType;
  errorBoundary?: boolean;
  performanceMonitoring?: boolean;
  theme?: string;
  variants?: Record<string, any>;
}

// 注册的组件接口
export interface RegisteredComponent {
  component: ComponentType<any>;
  metadata: ComponentMetadata;
  config: ComponentConfig;
  loader?: () => Promise<{ default: ComponentType<any> }>;
}

// 组件注册表
class ComponentRegistry {
  private components = new Map<string, RegisteredComponent>();
  private themes = new Map<string, any>();
  private loadedComponents = new Set<string>();
  private preloadQueue = new Set<string>();

  // 注册组件
  register(
    name: string,
    component: ComponentType<any> | (() => Promise<{ default: ComponentType<any> }>),
    metadata: ComponentMetadata,
    config: ComponentConfig = {}
  ): void {
    const isLazy = typeof component === 'function' && config.lazy !== false;
    
    const registeredComponent: RegisteredComponent = {
      component: isLazy ? lazy(component as any) : component as ComponentType<any>,
      metadata,
      config: {
        lazy: isLazy,
        preload: false,
        errorBoundary: true,
        performanceMonitoring: process.env.NODE_ENV === 'development',
        ...config,
      },
      loader: isLazy ? component as any : undefined,
    };

    this.components.set(name, registeredComponent);

    // 如果需要预加载
    if (config.preload) {
      this.preloadQueue.add(name);
      this.preloadComponent(name);
    }

    console.log(`📦 Component registered: ${name} (${metadata.category})`);
  }

  // 获取组件
  get(name: string): RegisteredComponent | undefined {
    return this.components.get(name);
  }

  // 获取所有组件
  getAll(): Map<string, RegisteredComponent> {
    return new Map(this.components);
  }

  // 按类别获取组件
  getByCategory(category: ComponentCategory): RegisteredComponent[] {
    return Array.from(this.components.values())
      .filter(comp => comp.metadata.category === category);
  }

  // 搜索组件
  search(query: string): RegisteredComponent[] {
    const lowerQuery = query.toLowerCase();
    return Array.from(this.components.values())
      .filter(comp => 
        comp.metadata.name.toLowerCase().includes(lowerQuery) ||
        comp.metadata.description.toLowerCase().includes(lowerQuery) ||
        comp.metadata.tags.some(tag => tag.toLowerCase().includes(lowerQuery))
      );
  }

  // 预加载组件
  async preloadComponent(name: string): Promise<void> {
    const registered = this.components.get(name);
    if (!registered || !registered.loader || this.loadedComponents.has(name)) {
      return;
    }

    try {
      await registered.loader();
      this.loadedComponents.add(name);
      console.log(`⚡ Component preloaded: ${name}`);
    } catch (error) {
      console.error(`❌ Failed to preload component ${name}:`, error);
    }
  }

  // 预加载所有标记的组件
  async preloadAll(): Promise<void> {
    const promises = Array.from(this.preloadQueue).map(name => 
      this.preloadComponent(name)
    );
    await Promise.allSettled(promises);
  }

  // 注册主题
  registerTheme(name: string, theme: any): void {
    this.themes.set(name, theme);
    console.log(`🎨 Theme registered: ${name}`);
  }

  // 获取主题
  getTheme(name: string): any {
    return this.themes.get(name);
  }

  // 获取组件统计信息
  getStats(): {
    total: number;
    byCategory: Record<ComponentCategory, number>;
    loaded: number;
    preloaded: number;
    deprecated: number;
    experimental: number;
  } {
    const components = Array.from(this.components.values());
    const byCategory = {} as Record<ComponentCategory, number>;

    // 初始化类别计数
    const categories: ComponentCategory[] = [
      'layout', 'navigation', 'input', 'display', 
      'feedback', 'overlay', 'editor', 'graph', 'utility'
    ];
    categories.forEach(cat => byCategory[cat] = 0);

    // 统计各类别组件数量
    components.forEach(comp => {
      byCategory[comp.metadata.category]++;
    });

    return {
      total: components.length,
      byCategory,
      loaded: this.loadedComponents.size,
      preloaded: this.preloadQueue.size,
      deprecated: components.filter(c => c.metadata.deprecated).length,
      experimental: components.filter(c => c.metadata.experimental).length,
    };
  }

  // 清理未使用的组件
  cleanup(): void {
    // 这里可以实现清理逻辑
    console.log('🧹 Component registry cleanup completed');
  }
}

// 全局注册表实例
export const componentRegistry = new ComponentRegistry();

// React Context for component registry
export const ComponentRegistryContext = React.createContext(componentRegistry);

// Hook for using component registry
export const useComponentRegistry = () => {
  return React.useContext(ComponentRegistryContext);
};

// 动态组件加载器
export interface DynamicComponentProps extends FullBaseProps {
  name: string;
  fallback?: ComponentType;
  onError?: (error: Error) => void;
  [key: string]: any;
}

export const DynamicComponent: React.FC<DynamicComponentProps> = ({
  name,
  fallback,
  onError,
  ...props
}) => {
  const registry = useComponentRegistry();
  const registered = registry.get(name);

  if (!registered) {
    const error = new Error(`Component "${name}" not found in registry`);
    if (onError) {
      onError(error);
    }
    console.error(error);
    return null;
  }

  const { component: Component, config } = registered;
  
  // 默认加载中组件
  const DefaultFallback = fallback || (() => (
    <div className="flex items-center justify-center p-4">
      <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary-600"></div>
      <span className="ml-2 text-sm text-gray-600">Loading {name}...</span>
    </div>
  ));

  // 错误边界组件
  const ErrorBoundary: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const [hasError, setHasError] = React.useState(false);
    const [error, setError] = React.useState<Error | null>(null);

    React.useEffect(() => {
      const handleError = (event: ErrorEvent) => {
        setHasError(true);
        setError(new Error(event.message));
        if (onError) {
          onError(new Error(event.message));
        }
      };

      if (config.errorBoundary) {
        window.addEventListener('error', handleError);
        return () => window.removeEventListener('error', handleError);
      }
    }, []);

    if (hasError && error) {
      return (
        <div className="p-4 border border-red-300 rounded-md bg-red-50">
          <h3 className="text-red-800 font-medium">组件加载失败</h3>
          <p className="text-red-600 text-sm mt-1">{error.message}</p>
          <button
            onClick={() => {
              setHasError(false);
              setError(null);
            }}
            className="mt-2 px-3 py-1 bg-red-600 text-white rounded text-sm hover:bg-red-700"
          >
            重试
          </button>
        </div>
      );
    }

    return <>{children}</>;
  };

  // 渲染组件
  const renderComponent = () => {
    if (config.lazy) {
      return (
        <Suspense fallback={<DefaultFallback />}>
          <Component {...props} />
        </Suspense>
      );
    }
    return <Component {...props} />;
  };

  if (config.errorBoundary) {
    return (
      <ErrorBoundary>
        {renderComponent()}
      </ErrorBoundary>
    );
  }

  return renderComponent();
};

// 组件注册装饰器
export function registerComponent(
  name: string,
  metadata: ComponentMetadata,
  config?: ComponentConfig
) {
  return function<T extends ComponentType<any>>(Component: T): T {
    componentRegistry.register(name, Component, metadata, config);
    return Component;
  };
}

// 批量注册组件
export function registerComponents(
  components: Array<{
    name: string;
    component: ComponentType<any>;
    metadata: ComponentMetadata;
    config?: ComponentConfig;
  }>
): void {
  components.forEach(({ name, component, metadata, config }) => {
    componentRegistry.register(name, component, metadata, config);
  });
}

// 导出默认注册表
export default componentRegistry;
